home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 3
/
Gold Medal Software - Volume 3 (Gold Medal) (1994).iso
/
graphics
/
3dvect30.arj
/
STARS.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-11-18
|
10KB
|
373 lines
; display backgound stars, 1024 stars. routine is designed so only stars
; which will be on the screen are calculated. this is first done with
; x angle indexing, then with y angle clipping, then with z distance clipping.
; this way, stars which most likely wont be visable are not rotated with those
; time-consuming IMUL's. a mode has also been added to make non-perfect 3d
; stars. this mode requires that the constants xstar and ystar be adjusted
; by the user the make the stars "look" the same as perfectly calculated stars
; however, when these values are adjusted correctly, this routine is about 40%
; faster. this can be done because the stars are at a constant distance from
; the camera.
.386p
jumps
code32 segment para public use32
assume cs:code32, ds:code32
include pmode.inc ; protected mode externals
include xmode.inc ; include externals for xmode routines
include macros.inc
include equ.inc ; every .asm should have access to this stuff
include 3d.inc
include stardata.inc
public show_stars
; angle tolerence (lower untill stars get clipped)
;largest equ 93 ; this is good without using z rotations in 320x400
largest equ 150 ; this is good with using z rotations in 320x400
; this is only used when perfect_stars = yes
zdistance equ 14500 ; z clipping parameter, 16384 = all stars clipped
xstar equ ratiox*4/128 ; these are divided by 4 to give decimals.
ystar equ ratioy*4/128 ; used when perfect_stars=no
starcolour equ 12 ; colour for star, 1st of four (indexed from palette)
number_of_stars equ 1024 ; must be 2^some_number
cut equ 5
;use_half_stars equ no ; both already defined in equ.inc
;perfect_stars equ no ; fast star calculation if no
smatrix dd 6 dup (0) ; star matrix, ematrix*xscale*yscale
angle_count dw 0
starhalfpoint dw 512 ;400,600? ; lower cutoff if use_half_stars = yes
we_is_out_of_here:
ret
show_stars:
movzx esi,eyeax ; get camera x angle
add si,16384 ; 1/4 quadrant
shr si,5 ; 32768/2^5 = 1024
mov ebp,esi
add bp,largest ; sweep to bottom
sub si,largest ; start from top
cmp bp,number_of_stars-cut
jle s okmax
mov bp,number_of_stars-cut
okmax:
cmp si,cut
jge s ok_min
mov si,cut ; looking almost directly up
ok_min:
movzx esi,xn1[esi]
movzx ebp,xn1[ebp]
mov ax,bp
sub ax,si
shl ax,2
mov angle_count,ax
shl si,2
;mov angle_count,number_of_stars
;mov esi,0 ; uncomment this!! (along with stuff below)
if use_half_stars eq yes
cmp si,starhalfpoint
jae s we_is_out_of_here
endif
call set_star_matrix ; pre-cal star matrix
more_stars:
movsx ax,sya[esi] ; star_y_angle
neg ax
shl ax,8
sub ax,eyeay
shr ax,8
movsx ax,al
mov bl,tol[esi] ; bx = tol *256
xor bh,bh
mov cx,bx
shr cx,1
add ax,cx
cmp ax,0 ; check left or right of screen
jl skipit
cmp ax,bx
jg skipit ; try removing these skipit jumps!!!
push esi
movsx ebx,sxl[esi] ; star_x_location
movsx ecx,syl[esi]
movsx ebp,szl[esi]
if perfect_stars eq yes
shl ebx,7 ; * for some accuracy
shl ecx,7
shl ebp,7
call srotatez ; star is eligable, calculate actual screen loc
;add esi,50000 ; try this too! (this is the best part)
cmp esi,zdistance ; clip if too close (not on apex of sphere)
jl abort_s
endif
call srotatex ; check tolerence in parts (saves imul's)
if perfect_stars eq yes
mov eax,edi ; some code from make3d routine (math.inc)
cdq
idiv esi ; if fast mode selected, avoid idiv's
mov edi,eax
endif
cmp di,xmins ; draw single point/bullet
jl s abort_s
cmp di,xmaxs
jge s abort_s
call srotatey ; x is ok, solve for y
if perfect_stars eq yes
mov eax,ecx
cdq
idiv ebp
mov ecx,eax
endif
cmp cx,ymins
jl s abort_s
cmp cx,ymaxs ; ymaxs1 if larger star (for high res screens)
jge abort_s
mov edi, current_page ; point to active vga page
add bx,xcent
add cx,ycent
movzx esi,cx
shl si,1
mov ax,[esi+fastimultable] ; get offset to start of line
mov cx, bx ; copy to extract plane # from
shr bx, 2 ; x offset (bytes) = xpos/4
add bx, ax ; offset = width*ypos + xpos/4
mov ax, map_mask_plane1 ; map mask & plane select register
and cl, plane_bits ; get plane bits
shl ah, cl ; get plane select value
out_16 sc_index, ax ; select plane
pop eax ; select colour for star
push eax
and al,3 ; four colours
add al,starcolour
movzx ebx,bx
mov b [edi+ebx],al ; draw pixel, red or blue is good
; add edi,xactual/4
; mov [edi+ebx],16 ; draw larger bullet/pixel
; if drawing larger star, change above code to this!
; cmp cx,ymaxs1
; jge s abort_s
abort_s:
pop esi
skipit:
if use_half_stars eq yes
cmp si,starhalfpoint
jae outhandle
else
cmp si,number_of_stars-1-cut
jae s outhandle
endif
inc si
dec angle_count
jnz more_stars
outhandle:
if useborders eq yes
mov ax,xmin
mov bx,xmax
mov cx,ymin
mov dx,ymax
dec bx
dec dx
mov lxupdate+0,ax
mov lxupdate+2,bx
mov lyupdate+0,cx
mov lyupdate+2,dx
endif
ret
; pre-multiply ematrix_row*constant_for_row
; to generate new matrix
; this can be done because we don't have any
; camera location offsets (stars are at a
; fixed distance from the camera)
align 16
if perfect_stars eq yes
set_star_matrix:
mov ebx,ematrix+0
cmul eax,ebx,ratiox
mov smatrix+0,eax
if usez eq yes ; if not using z rotation, ematrix+4 =0
mov ebx,ematrix+4
cmul eax,ebx,ratiox
mov smatrix+4,eax
endif
mov ebx,ematrix+8
cmul eax,ebx,ratiox
mov smatrix+8,eax
mov ebx,ematrix+12
cmul eax,ebx,ratioy
mov smatrix+12,eax
mov ebx,ematrix+16
cmul eax,ebx,ratioy
mov smatrix+16,eax
mov ebx,ematrix+20
cmul eax,ebx,ratioy
mov smatrix+20,eax
ret
; if perfect_stars = no, stars will not go through correct 3d calculation
; but will be calculated 40% faster. you must set the values xstar and
; ystar to 3d quick multipliers so this matrix calculation makes the
; stars "look" the same. I did this by moving the camera around and testing
; if the stars moved the same as the objects. I did this because the objects
; go through the correct 3d calculation and this gave me a base by which to
; adjust these numbers.
else
set_star_matrix:
mov ebx,ematrix+0
cmul eax,ebx,xstar
shr eax,2
mov smatrix+0,eax
if usez eq yes ; if not using z rotation, ematrix+4 =0
mov ebx,ematrix+4
cmul eax,ebx,xstar
shr eax,2
mov smatrix+4,eax
endif
mov ebx,ematrix+8
cmul eax,ebx,xstar
shr eax,2
mov smatrix+8,eax
mov ebx,ematrix+12
cmul eax,ebx,ystar
shr eax,2
mov smatrix+12,eax
mov ebx,ematrix+16
cmul eax,ebx,ystar
shr eax,2
mov smatrix+16,eax
mov ebx,ematrix+20
cmul eax,ebx,ystar
shr eax,2
mov smatrix+20,eax
ret
endif
; rotate star using smatrix (imported from math.inc)
align 16
srotatex:
mov eax,smatrix+8
imul ebp
shrd eax,edx,14
mov edi,eax
if usez eq yes
mov eax,smatrix+4
imul ecx
shrd eax,edx,14
add edi,eax
endif
mov eax,smatrix+0
imul ebx
shrd eax,edx,14
add edi,eax ; di = new x
ret
align 16
srotatey:
mov eax,smatrix+16
imul ecx
shrd eax,edx,14
mov ecx,eax
mov eax,smatrix+20
imul ebp
shrd eax,edx,14
add ecx,eax
mov eax,smatrix+12
imul ebx
shrd eax,edx,14
add ecx,eax ; cx = new y
mov ebp,esi
mov ebx,edi
ret
if perfect_stars eq yes
align 16
srotatez:
mov eax,ematrix+32
imul ebp
shrd eax,edx,14
mov esi,eax
mov eax,ematrix+28
imul ecx
shrd eax,edx,14
add esi,eax
mov eax,ematrix+24
imul ebx
shrd eax,edx,14
add esi,eax ; si = new z
ret
endif
code32 ends
end